package com.yanqu.road.server.manager.busyfarming;

import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.busyfarming.BusyFarmingGradeInfo;
import com.yanqu.road.entity.activity.busyfarming.BusyFarmingLand;
import com.yanqu.road.entity.activity.busyfarming.BusyFarmingUserData;
import com.yanqu.road.entity.activity.busyfarming.enums.eBusyFarmingLandState;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.activity.BusyFarmingBusiness;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.activity.BusyFarmingProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manger.ServerLanguageMgr;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossBusyFarming {

    private Logger logger = LogManager.getLogger(CrossBusyFarming.class.getName());

    private final Object lockObj = new Object();

    private ActivityInfo activityInfo;

    //serverId   userId
    private Map<Long, Map<Long, CrossBusyFarmingUserData>> userDataMap = new ConcurrentHashMap<>();


    public CrossBusyFarming(ActivityInfo activityInfo) {
        this.activityInfo = activityInfo;

    }

    /**
     * 果园等级配置
     */
    private static List<BusyFarmingGradeInfo> gradeInfoList;

    public void initConfig(){
        gradeInfoList = BusyFarmingBusiness.getGradeInfoList(activityInfo.getActivityId());
    }

    /**
     * 更新果园数据
     */
    public void upDateUserData(long serverId, List<BusyFarmingProto.BusyFarmingUserDataTemp> dataTempList) {
//        if(!userDataMap.containsKey(serverId)) {
//            synchronized (userDataMap) {
//                if (!userDataMap.containsKey(serverId)) {
//                    userDataMap.put(serverId, new ConcurrentHashMap<>());
//                }
//            }
//        }
        //Set<Long> oldSet = userDataMap.get(serverId).keySet();
        //Set<Long> toRemove = new HashSet<>();
        //for(long uid : oldSet){
        //    toRemove.add(uid);
        //}
        Map<Long, CrossBusyFarmingUserData> tempMap = new ConcurrentHashMap<>();
        for(BusyFarmingProto.BusyFarmingUserDataTemp dataTemp : dataTempList){
            CrossBusyFarmingUserData userData = new CrossBusyFarmingUserData();
            userData.setActivityId(activityInfo.getActivityId());
            userData.setServerId(serverId);
            userData.setUserId(dataTemp.getUserId());
            userData.setHomeGrade(dataTemp.getHomeGrade());
            userData.setFruitScore(dataTemp.getFruitScore());
            userData.setWateringTimes(dataTemp.getWateringTimes());
            userData.setBeWateringTimes(dataTemp.getBeWateringTimes());
            userData.setStealTimes(dataTemp.getStealTimes());
            userData.setBeStealTimes(dataTemp.getBeStealTimes());
            userData.setUserBaseInfo(PlayerBasePb.parseToUserBaseInfo(dataTemp.getUserBaseInfo()));
            userData.setLanguage(dataTemp.getLanguage());
            for(BusyFarmingProto.BusyFarmingLandTemp landTemp : dataTemp.getLandList()){
                userData.getLandMap().put(landTemp.getId(), landTemp);
            }
            tempMap.put(dataTemp.getUserId(), userData);
            //userDataMap.get(serverId).put(dataTemp.getUserId(), userData);
            //toRemove.remove(dataTemp.getUserId());
        }
        userDataMap.put(serverId, tempMap);
        //for(long userId : toRemove){
        //    userDataMap.get(serverId).remove(userId);
        //}
        logger.info("serverId {} has {} users land", serverId, userDataMap.get(serverId).keySet().size());
    }

    /**
     * 查找三个随机玩家的果园
     */
    public void searchStealList(long serverId, String unionUid, long playerId, List<Long> friend, int grade, int gradeRange, List<Long> stolen) {

        List<CrossBusyFarmingUserData> userDataList = new ArrayList<>();

        //每个区服选择三个玩家
        Set<Long> serverIdList = userDataMap.keySet();
        for(long sid : serverIdList){
            userDataList.addAll(randomPerServer(sid, serverId, unionUid, playerId, friend, grade, gradeRange, stolen));
        }
        int ret = 0;

        //如果不足三个玩家，不限制等级范围，补足
        if(userDataList.size() < 3){
            for(long sid : serverIdList){
                if(userDataList.size() >= 3){
                    break;
                }
                for(CrossBusyFarmingUserData tempUserData : randomPerServer(sid, serverId, unionUid, playerId, friend, grade, 100, stolen)){
                    if(userDataList.size() >= 3){
                        break;
                    }
                    boolean exist = false;
                    for(CrossBusyFarmingUserData crossBusyFarmingUserData : userDataList){
                        if(crossBusyFarmingUserData.getUserId() == tempUserData.getUserId()){
                            exist = true;
                        }
                    }
                    if(!exist){
                        userDataList.add(tempUserData);
                    }
                }
            }
        }

        List<CrossBusyFarmingUserData> result = new ArrayList<>();
        if(userDataList.size() < 3){
            ret = GameErrorCode.E_BUSY_FARMING_ACTIVITY_STEAL_USER_NO_ENOUGH;
            //直接有几个返回几个
            for(CrossBusyFarmingUserData tempUserData : userDataList){
                result.add(tempUserData);
            }
        }else {
            Random random = new Random();
            for(int i = 0; i < 3; i++){
                int idx = random.nextInt(userDataList.size());
                result.add(userDataList.get(idx));
                userDataList.remove(idx);
            }
        }

        BusyFarmingProto.CrossBusyFarmingStealSearchRespMsg.Builder respMsg = BusyFarmingProto.CrossBusyFarmingStealSearchRespMsg.newBuilder();
        respMsg.setRet(ret);
        respMsg.setCsrf(0);//temp
        respMsg.setActivityId(activityInfo.getActivityId());
        for(CrossBusyFarmingUserData ud : result){
            BusyFarmingProto.CrossBusyFarmingStealDataTemp.Builder builder = getCrossStealDataBuilder(ud);
            respMsg.addSteal(builder);
        }
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_BUSY_FARMING_STEAL_SEARCH_FROM_CROSS, respMsg));
    }

    private BusyFarmingProto.CrossBusyFarmingStealDataTemp.Builder getCrossStealDataBuilder(CrossBusyFarmingUserData ud) {
        BusyFarmingProto.CrossBusyFarmingStealDataTemp.Builder builder = BusyFarmingProto.CrossBusyFarmingStealDataTemp.newBuilder();
        builder.setGrade(ud.getHomeGrade());
        builder.setServerId(ud.getServerId());
        builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(ud.getUserBaseInfo()));
        //暂时 带回土地数据
        builder.addAllLand(ud.getLandMap().values());
        builder.setUserId(ud.getUserId());
        return builder;
    }

    /**
     * 每个区服随机三个玩家
     */
    private List<CrossBusyFarmingUserData> randomPerServer(long sid, long serverId, String unionUid, long playerId, List<Long> friend, int grade, int gradeRange, List<Long> stolen) {
        Map<Long, CrossBusyFarmingUserData> tempDataMap = userDataMap.get(sid);
        if(tempDataMap == null || tempDataMap.size() == 0){
            return new ArrayList();
        }
        List<CrossBusyFarmingUserData> result = new ArrayList<>();
        List<CrossBusyFarmingUserData> tempResult = new ArrayList<>();
        Set<Long> userIdList = new HashSet<>();
        for(long uid : tempDataMap.keySet()){
            userIdList.add(uid);
        }
        //移除被偷玩家
        userIdList.removeAll(stolen);
        int max = grade + gradeRange;
        int min = Math.max(1, grade - gradeRange);
        if(serverId == sid){
            userIdList.remove(playerId);
            userIdList.removeAll(friend);
            for(long uid : userIdList){
                CrossBusyFarmingUserData userData = tempDataMap.get(uid);
                if(userData == null){
                    continue;
                }
                if(landHasState(userData, eBusyFarmingLandState.Watering.getIntValue())){
                    continue;
                }
                if((userData.getHomeGrade() <= max && userData.getHomeGrade() >= min)
                        && ("".equals(unionUid) || !unionUid.equals(userData.getUserBaseInfo().getUnionUid()))){
                    tempResult.add(userData);
                }
            }
        }else {
            for(long uid : userIdList){
                CrossBusyFarmingUserData userData = tempDataMap.get(uid);
                if(userData == null){
                    continue;
                }
                if(landHasState(userData, eBusyFarmingLandState.Watering.getIntValue())){
                    continue;
                }
                if((userData.getHomeGrade() <= max && userData.getHomeGrade() >= min)){
                    tempResult.add(userData);
                }
            }
        }
        Random random = new Random();
        for(int i = 0; i < 3; i++){
            int size = tempResult.size();
            if(size == 0){
                break;
            }
            int idx = random.nextInt(size);
            result.add(tempResult.get(idx));
            tempResult.remove(idx);
        }
        return result;
    }

    /**
     * 是否包含某个状态
     */
    public static boolean landHasState(CrossBusyFarmingUserData userData, int state) {
        for(BusyFarmingProto.BusyFarmingLandTemp land : userData.getLandMap().values()){
            if(land.getStatesList().contains(state)){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取玩家的果园详情
     */
    public void searchStealDetail(long serverId, long playerId, long userId, long userServerId) {
        int ret = 0;

        BusyFarmingProto.CrossBusyFarmingStealHomeDetailRespMsg.Builder respMsg = BusyFarmingProto.CrossBusyFarmingStealHomeDetailRespMsg.newBuilder();
        Map<Long, CrossBusyFarmingUserData> tempDataMap = userDataMap.get(userServerId);
        CrossBusyFarmingUserData userData;
        if(tempDataMap == null || (userData = tempDataMap.get(userId))  == null){
            //跨服无数据（1、向目标区服请求最新数据 或者 2、直接返回到请求的区服，用区服缓存的数据展示土地数据）
            ret = -1;
        }else {
            if(userData != null) {
                respMsg.setStealData(getCrossStealDataBuilder(userData));
            }else {
                ret = -1;
            }
        }
        respMsg.setRet(ret);
        respMsg.setServerId(userServerId);
        respMsg.setUserId(userId);
        MessageHelper.sendPacket(serverId, playerId, YanQuMessageUtils.buildMessage(Protocol.S_BUSY_FARMING_STEAL_SEARCH_DETAIL_FROM_CROSS, respMsg));
    }

    public Map<Long, Map<Long, CrossBusyFarmingUserData>> getUserDataMap() {
        return userDataMap;
    }

    public CrossBusyFarmingUserData getUserData(long serverId, long userId){
        Map<Long, CrossBusyFarmingUserData> map = userDataMap.get(serverId);
        if(map == null){
            return null;
        }
        return map.get(userId);
    }

    public BusyFarmingProto.BusyFarmingFriendHomeListRespMsg.Builder friendHomeList(long serverId, long playerId, int type,
              List<BusyFarmingProto.BusyFarmingFriendId> userList, boolean myCanWatering, int wateringLimit) {

        BusyFarmingProto.BusyFarmingFriendHomeListRespMsg.Builder respMsg = BusyFarmingProto.BusyFarmingFriendHomeListRespMsg.newBuilder();
        respMsg.setType(type);

        for(BusyFarmingProto.BusyFarmingFriendId user : userList){
            CrossBusyFarmingUserData userData = getUserData(user.getServerId(), user.getUserId());
            if(userData == null){
                continue;
            }
            boolean canWatering = myCanWatering && canWatering(userData, wateringLimit);
            respMsg.addFriend(getHomeTempBuilder(userData, canWatering, userData.getLanguage()));
        }

        return respMsg;
    }

    /**
     * 是否可浇水
     */
    public static boolean canWatering(CrossBusyFarmingUserData userData, int wateringTimesLimit) {
        //今日无被浇水次数
        if(userData.getBeWateringTimes() >= wateringTimesLimit){
            return false;
        }
        for(BusyFarmingProto.BusyFarmingLandTemp land : userData.getLandMap().values()){
            if(land.getStatesList().contains(eBusyFarmingLandState.Watering.getIntValue()) && land.getBeWateringTimes() == 0){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取果园等级名称
     */
    public String getHomeGradeName(int homeGrade, String language) {
        for(BusyFarmingGradeInfo gradeInfo : gradeInfoList){
            if(gradeInfo.getId() == homeGrade){
                return ServerLanguageMgr.getContent(gradeInfo.getName(), language);
            }
        }
        return "";
    }

    /**
     * 构建亲友果园简况
     */
    public BusyFarmingProto.BusyFarmingFriendHomeTemp.Builder getHomeTempBuilder(CrossBusyFarmingUserData userData, boolean canWatering, String language) {
        BusyFarmingProto.BusyFarmingFriendHomeTemp.Builder builder = BusyFarmingProto.BusyFarmingFriendHomeTemp.newBuilder();
        builder.setUserId(userData.getUserId());
        builder.setHomeGrade(userData.getHomeGrade());
        builder.setHomeGradeName(getHomeGradeName(userData.getHomeGrade(), language));
        builder.setWatering(canWatering);
        builder.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userData.getUserBaseInfo()));
        return builder;
    }

    public static void repair(int activityId) {


    }
}
